/*
 * Copyright © 2009 Gerald Isaac Schwarz
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package base;

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;

public class NewGameConfigurator extends JDialog implements Refreshable {
	
	private Engine engine;
	private ArrayList<Player> players;
	private JPanel display, buttonbar;
	private JButton confirm, cancel;
	private GridBagConstraints constraints = new GridBagConstraints();
	private NewGameConfigurator me = this;
	private boolean result = false;
	private BoardWidget board;
	private GUI gui;
	
	private ActionListener colorListener = new ActionListener() {

		@Override
		public void actionPerformed(ActionEvent e) {
			Player player = engine.getBoard().getPlayerById(Integer.parseInt(e.getActionCommand()));
			player.setColor(JColorChooser.showDialog(me, "Choose Your Color", player.getColor()));
			refresh();
		}
		
	};
	
	private void initialize(GameLoader gameLoader, GUI gui) {
		this.gui = gui;
		this.engine = gameLoader.getEngine();
		this.players = this.engine.getBoard().getPlayers();
		this.board = new BoardWidget(this.engine.getBoard());
		
		this.display = new JPanel();
		this.display.setLayout(new GridBagLayout());
		
		JPanel df = new JPanel();
		df.setLayout(new BoxLayout(df, BoxLayout.PAGE_AXIS));
		
		this.buttonbar = new JPanel();
		this.buttonbar.setLayout(new FlowLayout(FlowLayout.TRAILING));
		
		for (Player player : this.players) {
			JTextField textField = new JTextField(player.getName());
			textField.addCaretListener(new NameListener(player.getId()));
			
			JButton button = new JButton("Change color");
			button.setActionCommand(player.getId() + "");
			button.addActionListener(this.colorListener);
			
			JPanel panel = new JPanel();
			panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
			panel.add(textField);
			panel.add(button);
			
			df.add(panel);
		}
		
		this.constraints.insets = new Insets(5, 5, 5, 5);
		this.constraints.anchor = GridBagConstraints.FIRST_LINE_START;
		this.constraints.fill = GridBagConstraints.HORIZONTAL;
		this.constraints.gridy = 0;
		this.constraints.gridx = 0;
		this.constraints.weighty = 1;
		this.constraints.weightx = 1;
		
		this.display.add(df, this.constraints);
		
		this.cancel = new JButton("Cancel");
		this.cancel.setMnemonic(KeyEvent.VK_C);
		this.cancel.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				me.setResult(false);
				me.dispose();
				refresh();
			}
			
		});
		
		this.confirm = new JButton("OK");
		this.confirm.setMnemonic(KeyEvent.VK_O);
		this.confirm.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				me.setResult(true);
				me.dispose();
				refresh();
			}
			
		});
		this.buttonbar.add(this.cancel);
		this.buttonbar.add(this.confirm);
		
		this.getContentPane().setLayout(new GridBagLayout());
		
		this.constraints.weightx = 0;
		this.constraints.weighty = 1;
		this.constraints.gridx = 0;
		this.constraints.gridy = 0;
		this.constraints.anchor = GridBagConstraints.FIRST_LINE_START;
		this.constraints.fill = GridBagConstraints.BOTH;
		JScrollPane pane = new JScrollPane(this.display);
		pane.setMinimumSize(new Dimension(300, 20));
		this.getContentPane().add(pane, this.constraints);
		
		this.constraints.weightx = 0;
		this.constraints.weighty = 0;
		this.constraints.gridy = 1;
		this.constraints.gridx = 1;
		this.constraints.anchor = GridBagConstraints.LAST_LINE_END;
		this.constraints.fill = GridBagConstraints.BOTH;
		this.getContentPane().add(this.buttonbar, this.constraints);
		
		this.constraints.weightx = 1;
		this.constraints.weighty = 1;
		this.constraints.gridy = 0;
		this.constraints.gridx = 1;
		JPanel panel = new JPanel();
		panel.setLayout(new GridBagLayout());
		panel.add(this.getBoardWidget());
		JScrollPane scrollPane = new JScrollPane(panel);
		this.getContentPane().add(scrollPane, this.constraints);
		
		this.getBoardWidget().setZoom(25);
		this.setMinimumSize(new Dimension(600, 350));
		this.setVisible(true);
	}
	
	public NewGameConfigurator(GameLoader gameLoader, GamePlayer gui) {
		super(gui, "New Game", true);
		this.initialize(gameLoader, gui);
	}
	
	private BoardWidget getBoardWidget() {
		return this.board;
	}

	public Engine getEngine() {
		return this.engine;
	}
	
	private void setResult(boolean result) {
		this.result = result;
	}

	public boolean isResult() {
		return result;
	}
	
	class NameListener implements CaretListener {
		private int id;

		public NameListener(int id) {
			this.id = id;
		}

		@Override
		public void caretUpdate(CaretEvent e) {
			String newName = ((JTextField) e.getSource()).getText();
			Player player = engine.getBoard().getPlayerById(this.id);
			String oldName = player.getName();
			
			if (!newName.equals(oldName)) {
				player.setName(newName);
			}
		}
	}

	@Override
	public void refresh() {
		if (this.getBoardWidget() != null) {
			this.getBoardWidget().revalidate();
			this.getBoardWidget().repaint();
		}
		
		this.validate();
		this.gui.refresh();
	}
}
